﻿//------------------------------------------------------------------------------
// <copyright file="FullConfigurationSwapper.cs" company="CommerceServer.net, Inc">
//    (c) 2012 CommerceServer.net, Inc. and its affiliates. All rights reserved.
// </copyright>
// <summary></summary>
//------------------------------------------------------------------------------ 
namespace CommerceServerContrib.CodeGeneration.ConfigurationHelpers
{
    using System;
    using System.Configuration;
    using System.Linq;
    using System.Reflection;

    public class FullConfigurationSwapper : IDisposable
    {
        private readonly string oldConfig =
                AppDomain.CurrentDomain.GetData("APP_CONFIG_FILE").ToString();

            private bool disposedValue;

            public FullConfigurationSwapper(string path)
            {
                AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", path);
                ResetConfigMechanism();
            }

            public void Dispose()
            {
                if (!this.disposedValue)
                {
                    AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", this.oldConfig);
                    ResetConfigMechanism();
                    this.disposedValue = true;
                }

                GC.SuppressFinalize(this);
            }

            private static void ResetConfigMechanism()
            {
                typeof(ConfigurationManager).GetField("s_initState", BindingFlags.NonPublic | BindingFlags.Static).SetValue(null, 0);

                typeof(ConfigurationManager).GetField("s_configSystem", BindingFlags.NonPublic | BindingFlags.Static).SetValue(null, null);

                typeof(ConfigurationManager)
                    .Assembly.GetTypes()
                    .Where(x => x.FullName == "System.Configuration.ClientConfigPaths")
                    .First()
                    .GetField("s_current", BindingFlags.NonPublic | BindingFlags.Static)
                    .SetValue(null, null);
            }
    }
}
